package com.dkts.oil.test;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.time.Duration;
import java.time.Instant;
import java.util.*;

public class AISTrajectorySegmenterV1 {

    private static final long SEGMENT_GAP_SECONDS = 600; // 超过10分钟分段

    public static void main(String[] args) throws Exception {
        File csvFile = new File("C:\\Users\\heyou\\Documents\\WeChat Files\\wxid_86da35bc9zvi21\\FileStorage\\File\\2025-05\\c9a6717b7d2f5293cf7cd2ed05a0494c_2e2437ef9cd58c0d39af05569deeb4be_8.csv"); // 替换为你的CSV路径
        Reader reader = new FileReader(csvFile);
        CSVParser parser = CSVFormat.DEFAULT.withFirstRecordAsHeader().parse(reader);

        // 将数据按 MMSI 分组
        Map<String, List<CSVRecord>> mmsiMap = new HashMap<>();
        for (CSVRecord record : parser) {
            String mmsi = record.get("mmsi");
            mmsiMap.computeIfAbsent(mmsi, k -> new ArrayList<>()).add(record);
        }

        ObjectMapper mapper = new ObjectMapper();

        // 遍历每个 MMSI 的轨迹
        for (Map.Entry<String, List<CSVRecord>> entry : mmsiMap.entrySet()) {
            String mmsi = entry.getKey();
            List<CSVRecord> records = entry.getValue();

            // 排序
            records.sort(Comparator.comparing(r -> Long.parseLong(r.get("time"))));

            // 轨迹分段
            List<List<CSVRecord>> segments = segmentTrajectory(records);

            // 每个 MMSI 建文件夹
            File dir = new File("output/" + mmsi);
            if (!dir.exists()) dir.mkdirs();

            // 输出每段为一个 geojson
            for (int i = 0; i < segments.size(); i++) {
                List<CSVRecord> segment = segments.get(i);

                ObjectNode featureCollection = mapper.createObjectNode();
                featureCollection.put("type", "FeatureCollection");
                ArrayNode features = mapper.createArrayNode();

                ObjectNode feature = mapper.createObjectNode();
                feature.put("type", "Feature");

                // 构造 LineString
                ObjectNode geometry = mapper.createObjectNode();
                geometry.put("type", "LineString");
                ArrayNode coordinates = mapper.createArrayNode();
                for (CSVRecord r : segment) {
                    ArrayNode coord = mapper.createArrayNode();
                    coord.add(Double.parseDouble(r.get("lon")));
                    coord.add(Double.parseDouble(r.get("lat")));
                    coordinates.add(coord);
                }
                geometry.set("coordinates", coordinates);
                feature.set("geometry", geometry);

                // 构造属性
                ObjectNode properties = mapper.createObjectNode();
                properties.put("mmsi", mmsi);
                properties.put("segment_index", i + 1);
                properties.put("start_time", segment.get(0).get("time"));
                properties.put("end_time", segment.get(segment.size() - 1).get("time"));
                feature.set("properties", properties);

                features.add(feature);
                featureCollection.set("features", features);

                File outFile = new File(dir, "segment_" + (i + 1) + ".geojson");
                try (FileWriter writer = new FileWriter(outFile)) {
                    mapper.writerWithDefaultPrettyPrinter().writeValue(writer, featureCollection);
                }
            }
        }

        System.out.println("轨迹分段输出完成。");
    }

    // 轨迹分段逻辑
    private static List<List<CSVRecord>> segmentTrajectory(List<CSVRecord> records) {
        List<List<CSVRecord>> segments = new ArrayList<>();
        List<CSVRecord> currentSegment = new ArrayList<>();

        for (int i = 0; i < records.size(); i++) {
            CSVRecord curr = records.get(i);
            if (currentSegment.isEmpty()) {
                currentSegment.add(curr);
            } else {
                CSVRecord prev = records.get(i - 1);
                long delta = timeDiffSeconds(prev.get("time"), curr.get("time"));
                if (delta > SEGMENT_GAP_SECONDS) {
                    segments.add(currentSegment);
                    currentSegment = new ArrayList<>();
                }
                currentSegment.add(curr);
            }
        }
        if (!currentSegment.isEmpty()) {
            segments.add(currentSegment);
        }
        return segments;
    }

    // 时间差（秒）
    private static long timeDiffSeconds(String t1, String t2) {
        Instant i1 = Instant.ofEpochSecond(Long.parseLong(t1));
        Instant i2 = Instant.ofEpochSecond(Long.parseLong(t2));
        return Duration.between(i1, i2).abs().getSeconds();
    }
}
